/******************************************************************************
 * SVN­Version­Information:
 * ­­­­­­­­­­­­­­­­­­­­­­­­---------------------
 * $LastChangedRevision: 6 $
 * $LastChangedBy: c.a.duevel $
 * $LastChangedDate: 2009-08-26 15:12:37 +0000 (Wed, 26 Aug 2009) $
 * $HeadURL: http://robofight.googlecode.com/svn/trunk/ClientJava/src/de/hft_stuttgart/robofight/client/java/JBotShop.java $
 ******************************************************************************/
package de.hft_stuttgart.robofight.client.java;

import de.hft_stuttgart.botwar.common.models.ArmamentInfo;
import de.hft_stuttgart.botwar.common.models.ChassisInfo;
import de.hft_stuttgart.botwar.common.models.NewRobotInfo;
import de.hft_stuttgart.botwar.common.models.RobotInfo;

import de.hft_stuttgart.botwar.common.models.ShieldInfo;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author michael.rieker@web.de
 */
public class JBotShop {

    private JPlayer jPlayer;
    private String robotName = "";
    private int coins = 0;
    private String armament = "";
    private String chassis = "";
    private String shield = "";
    private int maxWeight = 0;
    private int currentWeight = 0;
    private int amountArmament = 0;
    private int amountChassis = 0;
    private int amountShield = 0;
    private int amountSpecialItem = 0;
    private boolean armamentSelected = false;
    private boolean chassisSelected = false;
    private boolean shieldSelected = false;
    private boolean specialItemSelected = false;
    private List<ChassisInfo> allChassis = null;
    private List<ShieldInfo> allShields = null;
    private List<ArmamentInfo> allArmaments = null;
    private List<RobotInfo> allRobots = null;
    private int weightShield = 0;
    private int weightArmament = 0;
    private int healthOfShield = 0;
    private int firePower = 0;
    private String[] allRobotAsArray;

    /**
     * Creates a new object of a botshop.
     * @param jPlayer need a JPlayer as param
     */
    public JBotShop(final JPlayer jPlayer) {
        this.jPlayer = jPlayer;
        initialize();
    }

    /**
     * For JUnit Tests only.
     */
    public JBotShop() {
    }

    /**
     * Initialize all needed data.
     */
    public final void initialize() {
        try {
            allChassis = jPlayer.getPlayer().getAvailableChassises();
            allShields = jPlayer.getPlayer().getAvailableShields();
            allArmaments = jPlayer.getPlayer().getAvailableArmaments();
            getAllRobots();
            this.coins = (((int) jPlayer.getPlayer().getCoins()) -
                    getAmountOfCoinsOfAllBots());

        } catch (RemoteException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Returns the whole value of all bots in coins.
     * @return amountBotsInCoins sum of coins of all bots
     */
    public int getAmountOfCoinsOfAllBots() throws RemoteException {
        allRobots = jPlayer.getPlayer().getAvailableRobots();
        int amountBotsInCoins = 0;
        for (RobotInfo robotInfo : allRobots) {
            amountBotsInCoins += robotInfo.getCompleteCost();
        }
        return amountBotsInCoins;
    }

    /**
     * Sets the name of a robot.
     * @param robotName sets the name of a bot
     */
    public final void setName(final String robotName) {
        this.robotName = robotName;
    }

    /**
     * Returns the name of the robot.
     * @return String robotName
     */
    public final String getName() {
        return robotName;
    }

    /**
     * Sets the max weight of a chassis.
     * @param maxWeight sets the max weight of a chassis
     */
    public final void setMaxWeight(final int maxWeight) {
        this.maxWeight = maxWeight;
    }

    /**
     * Returns the max weight of a chassis.
     * @return maxWeight
     */
    public final int getMaxWeight() {
        return maxWeight;
    }

    /**
     * Adds the choosen weight to the current weight.
     * @param weight sets the current weight of a bot
     */
    public final void setCurrentWeight(final int weight) {
        this.currentWeight += weight;
    }

    /**
     * Returns the current weight.
     * @return currentWeight
     */
    public final int getCurrentWeight() {
        return currentWeight;
    }

    /**
     * Return true, if a armament is allready selected.
     * @return boolean armamentSelected
     */
    public final boolean isArmamentSelected() {
        return armamentSelected;
    }

    /**
     * Sets true, if a armament is selected. False, if the armament isn't
     * selected.
     * @param armamentSelected needs a boolean as param.
     */
    public final void setArmamentSelected(final boolean armamentSelected) {
        this.armamentSelected = armamentSelected;
    }

    /**
     * Return true, if a chassis is allready selected.
     * @return boolean chassisSelected
     */
    public final boolean isChassisSelected() {
        return chassisSelected;
    }

    /**
     * Sets true, if a chassis is selected. False, if the chassis isn't
     * selected.
     * @param chassisSelected boolean if a chassis is selected
     */
    public final void setChassisSelected(final boolean chassisSelected) {
        this.chassisSelected = chassisSelected;
    }

    /**
     * Return true, if a shield is allready selected.
     * @return shieldSelected boolean if a shield is selected
     */
    public final boolean isShieldSelected() {
        return shieldSelected;
    }

    /**
     * Sets true, if a shield is selected. False, if the shield isn't
     * selected.
     * @param shieldSelected sets the selected shield
     */
    public final void setShieldSelected(final boolean shieldSelected) {
        this.shieldSelected = shieldSelected;
    }

    /**
     * Return true, if a special item is allready selected.
     * @return boolean specialItemSelected
     */
    public final boolean isSpecialItemSelected() {
        return specialItemSelected;
    }

    /**
     * Sets true, if a special item is selected. False, if the special item
     * isn't selected.
     * @param specialItemSelected boolean if a special item is selected
     */
    public final void setSpecialItemSelected(
            final boolean specialItemSelected) {

        this.specialItemSelected = specialItemSelected;
    }

    /**
     * Sets the amount of the selected armament.
     * @param amountArmament sets the amount of the current selected armament
     */
    public final void setAmountArmament(final int amountArmament) {
        this.amountArmament = amountArmament;
    }

    /**
     * Sets the amount of the selected chassis.
     * @param amountChassis sets the amount of the current selected chassis
     */
    public final void setAmountChassis(final int amountChassis) {
        this.amountChassis = amountChassis;
    }

    /**
     * Sets the amount of the selected shield.
     * @param amountShield sets the amount of the current selected shield
     */
    public final void setAmountShield(final int amountShield) {
        this.amountShield = amountShield;
    }

    /**
     * Sets the amount of the selected special item.
     * @param amountSpecialItem sets the amount of a special item
     */
    public final void setAmountSpecialItem(final int amountSpecialItem) {
        this.amountSpecialItem = amountSpecialItem;
    }

    /**
     * Returns the amount of the selected armament.
     * @return amountArmament
     */
    public final int getAmountArmament() {
        return amountArmament;
    }

    /**
     * Returns the amount of the selected chassis.
     * @return amountchassis
     */
    public final int getAmountChassis() {
        return amountChassis;
    }

    /**
     * Returns the amount of the selected shield.
     * @return amountShield
     */
    public final int getAmountShield() {
        return amountShield;
    }

    /**
     * Returns the amount of the selected special item.
     * @return amountSpecialItem
     */
    public final int getAmountSpecialItem() {
        return amountSpecialItem;
    }

    /**
     * Sets the current weight of the selected shield.
     * @param weightShield set the weight of the current selected shield
     */
    public final void setWeightShield(final int weightShield) {
        this.weightShield = weightShield;
    }

    /**
     * Returns the current weight of the selected shield.
     * @return weightShield
     */
    public final int getWeightShield() {
        return weightShield;
    }

    /**
     * Sets the health of a shield.
     * @param healthOfShield sets the health of the current selected shield
     */
    public final void setHealthOfShield(final int healthOfShield) {
        this.healthOfShield = healthOfShield;
    }

    /**
     * Returns the health of a shield.
     * @return healthOfShield
     */
    public final int getHealthOfShield() {
        return healthOfShield;
    }

    /**
     * Sets the firepower of the current armament.
     * @param firePower the fire power of a weapon
     */
    public final void setFirePower(final int firePower) {
        this.firePower = firePower;
    }

    /**
     * Returns the firepower of the current armament.
     * @return firePower the fire power of a weapon
     */
    public final int getFirePower() {
        return firePower;
    }

    /**
     * Sets the current weight of the selected armament.
     * @param weightArmament sets the weight of the current selected item
     */
    public final void setWeightArmament(final int weightArmament) {
        this.weightArmament = weightArmament;
    }

    /**
     * Returns the current weight of the selected armament.
     * @return weightArmament
     */
    public final int getWeightArmament() {
        return weightArmament;
    }

    /**
     * Returns a list of chassis infos as a string list.
     * Contains sequential name, cost, maxSpeed, maxWeight.
     * @return List of objects allChassis
     * @throws java.rmi.RemoteException throws a RemoteException
     */
    public final List<Object> getAllChassis() throws RemoteException {

        List<Object> ret = new ArrayList<Object>();
        for (int i = 0; i < allChassis.size(); i++) {
            List<Object> tmp = new ArrayList<Object>();
            tmp.add(allChassis.get(i).getName());
            tmp.add(allChassis.get(i).getCost());
            tmp.add(allChassis.get(i).getWeight());
            tmp.add(allChassis.get(i).getSpeed());
            ret.add(tmp);
        }
        return ret;
    }

    /**
     * Returns the name of all chassis
     * @return ret all chassis
     */
    public final String[] getNameOfChassis() {
        String[] ret = new String[allChassis.size()];
        for (int i = 0; i < allChassis.size(); i++) {
            ret[i] = allChassis.get(i).getName() +
                    ", " + allChassis.get(i).getCost() +
                    "$, maxLoad: " + allChassis.get(i).getWeight() + "kg";
        }
        return ret;
    }

    /**
     * Returns the name of all shields
     * @return ret all shields
     */
    public final String[] getNameOfShields() {
        String[] ret = new String[allShields.size()];
        for (int i = 0; i < allShields.size(); i++) {
            ret[i] = allShields.get(i).getName() +
                    ", " + allShields.get(i).getCost() +
                    "$, H: " + allShields.get(i).getHealth() +
                    ", " + allShields.get(i).getWeight() + "kg";
        }
        return ret;
    }

    /**
     * Returns the name of all armaments
     * @return ret all armaments
     */
    public final String[] getNameOfArmaments() {
        String[] ret = new String[allArmaments.size()];
        for (int i = 0; i < allArmaments.size(); i++) {
            ret[i] = allArmaments.get(i).getName() +
                    ", " + allArmaments.get(i).getCost() +
                    "$, Pwr: " + allArmaments.get(i).getFirePower() +
                    ", " + allArmaments.get(i).getWeight() + "kg"+
                    ", Range: " + allArmaments.get(i).getDistance();
        }
        return ret;
    }

    /**
     * Returns a list of shield infos as a string list.
     * Contains sequential name, cost, weight, health.
     * @return List of object allShields
     * @throws java.rmi.RemoteException throws a RemoteException
     */
    public final List<Object> getAllShields() throws RemoteException {
        List<Object> ret = new ArrayList<Object>();
        for (int i = 0; i < allShields.size(); i++) {
            List<Object> tmp = new ArrayList<Object>();
            tmp.add(allShields.get(i).getName());
            tmp.add(allShields.get(i).getCost());
            tmp.add(allShields.get(i).getWeight());
            tmp.add(allShields.get(i).getHealth());
            ret.add(tmp);
        }
        return ret;
    }

    /**
     * Returns a list of armament infos as a string list.
     * Contains sequential name, cost, weight, power, minDistance, maxDistance.
     * @return List of objects allArmaments
     * @throws java.rmi.RemoteException throws a RemoteException
     */
    public final List<Object> getAllArmaments() throws RemoteException {

        List<Object> ret = new ArrayList<Object>();
        for (int i = 0; i < allArmaments.size(); i++) {
            List<Object> tmp = new ArrayList<Object>();
            tmp.add(allArmaments.get(i).getName());
            tmp.add(allArmaments.get(i).getCost());
            tmp.add(allArmaments.get(i).getWeight());
            tmp.add(allArmaments.get(i).getFirePower());
            tmp.add(allArmaments.get(i).getDistance());
            ret.add(tmp);
        }
        return ret;
    }

    /**
     * Returns a list of special items infos.
     * @return List of objects allSpecialItems
     * @throws java.rmi.RemoteException throws a RemoteException
     */
    public final List<String> getAllSpecialItems() throws RemoteException {
        return null;
    }

    /**
     * Returns a List of all bots a player have.
     * Contains sequential name, completeCost, chassis, shield, armament.
     * @return List of objects of all bots
     * @throws java.rmi.RemoteException throws a RemoteException
     */
    public final List<Object> getAllRobots() throws RemoteException {
        List<Object> ret = new ArrayList<Object>();
        allRobots = jPlayer.getPlayer().getAvailableRobots();
        allRobotAsArray = new String[allRobots.size()];
        for (int i = 0; i < allRobots.size(); i++) {
            String tmpBot = "";
            List<Object> tmp = new ArrayList<Object>();
            tmp.add(allRobots.get(i).getRobotName());
            tmpBot = allRobots.get(i).getRobotName() + ", Level:";
            tmpBot = tmpBot + allRobots.get(i).getLevelRank() + ", ";
            tmp.add(allRobots.get(i).getCompleteCost());
            tmp.add(allRobots.get(i).getChassis().getName());
            tmpBot = tmpBot + allRobots.get(i).getChassis().getName() + ", ";
            tmp.add(allRobots.get(i).getShield().getName());
            tmpBot = tmpBot + allRobots.get(i).getShield().getName() + ", ";
            tmp.add(allRobots.get(i).getArmament().getName());
            tmpBot = tmpBot + allRobots.get(i).getArmament().getName();
            tmp.add(allRobots.get(i).getRobotID());
            tmp.add(allRobots.get(i).getChassis().getWeight());
            tmp.add(allRobots.get(i).getShield().getHealth());
            tmp.add(allRobots.get(i).getArmament().getFirePower());
            tmp.add(allRobots.get(i).getChassis().getCost());
            tmp.add(allRobots.get(i).getShield().getCost());
            tmp.add(allRobots.get(i).getArmament().getCost());
            ret.add(tmp);
            allRobotAsArray[i] = tmpBot;
        }
        return ret;
    }

    /**
     * Returns a array with all robots.
     * @return allRobotAsArray array with all robots
     * @throws java.rmi.RemoteException throws RemoteException
     */
    public final String[] getAllRobotsAsArray() throws RemoteException {
        return allRobotAsArray;
    }

    /**
     * Returns a list with all items of a bot.
     * Contains sequantial chassis, shield, armament, armament cost,
     * chassis cost, shield cost, current weight, maxWeight, robotName,
     * shield weight, armament weight.
     * @return List of objects
     */
    public final List<Object> getAllRobotsItems() {
        List<Object> ret = new ArrayList<Object>();
        for (int i = 0; i < allRobots.size(); i++) {
            List<Object> tmp = new ArrayList<Object>();
            tmp.add(allRobots.get(i).getChassis().getName());
            tmp.add(allRobots.get(i).getShield().getName());
            tmp.add(allRobots.get(i).getArmament().getName());
            tmp.add(allRobots.get(i).getArmament().getCost());
            tmp.add(allRobots.get(i).getChassis().getCost());
            tmp.add(allRobots.get(i).getShield().getCost());
            int cuWeight = allRobots.get(i).getShield().getWeight() +
                    allRobots.get(i).getArmament().getWeight();

            tmp.add(cuWeight);
            tmp.add(allRobots.get(i).getChassis().getWeight());
            tmp.add(allRobots.get(i).getRobotName());
            tmp.add(allRobots.get(i).getShield().getWeight());
            tmp.add(allRobots.get(i).getArmament().getWeight());
            tmp.add(allRobots.get(i).getChassis().getWeight());
            tmp.add(allRobots.get(i).getShield().getHealth());
            tmp.add(allRobots.get(i).getArmament().getFirePower());
            ret.add(tmp);
        }
        return ret;
    }

    /**
     * Sets a armament of a robot.
     * @param armament sets the current selected armament
     */
    public final void setArmament(final String armament) {
        this.armament = armament;
    }

    /**
     * Sets a chassis of a robot.
     * @param chassis sets the selected chassis
     */
    public final void setChassis(final String chassis) {
        this.chassis = chassis;
    }

    /**
     * Returns the name of the current chassis.
     * @return selected chassis
     */
    public final String getChassis() {
        return chassis;
    }

    /**
     * Returns the name of the current shield.
     * @return String selected Shield.
     */
    public final String getShield() {
        return shield;
    }

    /**
     * Returns the name of the current armament.
     * @return String selected armament.
     */
    public final String getArmament() {
        return armament;
    }

    /**
     * Sets a shield of a robot.
     * @param shield sets the name of the current selected shield
     */
    public final void setShield(final String shield) {
        this.shield = shield;
    }

    /**
     * Returns the coins left.
     * @return coins the current amount of coins in int
     */
    public final int getCoins() {
        return coins;
    }

    /**
     * Sets the new amount of coins.
     * @param coins sets the current amount of coins
     */
    public final void setCoins(final int coins) {
        this.coins += coins;
    }

    /**
     * Sales a bot. Needs the bot id as param.
     * @param botID needs the botId for saling this
     * @throws java.rmi.RemoteException throws a RemoteException
     */
    public final String saleBot(final Integer botID) {
        String ret = null;
        try {
            jPlayer.getPlayer().removeRobot((int) botID);
        } catch (UnsupportedOperationException ex) {
            ret = ex.getMessage();
        } catch (RemoteException ex){
            ret = ex.getMessage();
        }
        return ret;
    }

    /**
     * Current amount of bots
     * @return amount of bots
     * @throws java.rmi.RemoteException throws RemoteException
     */
    public final int getCurrentCoinsFromDB() throws RemoteException {
        return ((int) jPlayer.getPlayer().getCoins() -
                getAmountOfCoinsOfAllBots());
    }

    /**
     * 
     * @return
     * @throws java.rmi.RemoteException
     */
    public final int getDBCoinsMinusItems() throws RemoteException {
        return getCurrentCoinsFromDB() - getAmountChassis() - getAmountArmament() - getAmountShield();
    }

    /**
     * Check all params.
     * @return boolean true or false
     */
    public final boolean checkParams(){
        if (isChassisSelected() && isShieldSelected() &&
                isArmamentSelected() && !robotName.equals("")) {

                    return true;
        }
        return false;
    }

    /**
     * Submits and save the new created robot.
     * @return ret boolean true, if saling was successfull
     */
    public final String submit() {
        String ret = null;
        try {
            jPlayer.getPlayer().saveRobot(
                    new NewRobotInfo(this.robotName, this.chassis,
                    this.shield, this.armament));
            
            initialize();
        } catch (UnsupportedOperationException ex) {
            ret = ex.getMessage();
        }
        catch (RemoteException ex) {
            ret = ex.getMessage();
        }
        return ret;
    }
}
